home *** CD-ROM | disk | FTP | other *** search
/ The X-Philes (2nd Revision) / The X-Philes Number 1 (1995).iso / xphiles / hp48_2 / grob2ps < prev    next >
Text File  |  1995-03-31  |  10KB  |  404 lines

  1. Path: seq!spell
  2. From: Johan Pensar RT <jpensar@ra.abo.fi>
  3. Subject:  v01i032:  grob2ps - grob2ps translator v1.0, Part01/01
  4. Newsgroups: comp.sources.hp48
  5. Followup-To: comp.sys.hp48
  6. Approved: spell@seq.uncwil.edu
  7.  
  8. Checksum:  182002788 (verify with brik -cv)
  9. Submitted-by: Johan Pensar RT <jpensar@ra.abo.fi>
  10. Posting-number: Volume 1, Issue 32
  11. Archive-name: grob2ps/part01
  12.  
  13.  
  14. [ If anyone wants a copy of this program compiled for the PC let
  15. me know and i'll post a copy. Send your default settings. -Chris ]
  16.  
  17. BEGIN_RDME grob2ps.rdm
  18. For all of you working on workstations or PC's connected to PostScript
  19. laserwriters, here is a program converting a hp48 GROB to PostScript.
  20.  
  21. I know of programs for conversion of GROB's to epson, portable bitmap and
  22. tiff formats but no program converting directly to PostScript, maybe I 
  23. have missed it? 
  24. Anyway I wrote this program because I needed to document some programs,
  25. and the documents should include some screendumps. Because i use TeX, the 
  26. only possible format was PostScript.
  27.  
  28. The program is written in C and compiles on my SUN Sparcstation using GNU C, 
  29. and also on PC's using Microsoft C.
  30.  
  31. US users have to change the PAPERWIDTH and PAPERHEIGHT #defines to fit their
  32. papersize.
  33.  
  34. END_RDME
  35.  
  36. BEGIN_DOC grob2ps.doc
  37.  
  38. Program:  grob2ps, a hp48 GROB to PostScript translator
  39.  
  40. Author:   Johan Pensar, (c) 1991, may be freely copied as long as all
  41.           copyright notices are preserved.
  42.  
  43. Version:  1.0, 03.09.91
  44.  
  45. Compiler: Microsoft C or GNU C
  46.  
  47. Usage: 
  48.  
  49.   For a description on how to save and transfer a GROB to another computer, 
  50.   see the documentation for the grob2tif program on the HP 82208 A Serial 
  51.   Interface Kit Disk.
  52.  
  53.   This program, grob2ps, works in a similar way to the grob2tif program 
  54.   on the hp disk, but with some extentions.
  55.   If a sourcefilename is supplied, the program reads the file instead of
  56.   stdin. If a destinationfilename is supplied, the program opens it instead
  57.   of stdout.
  58.  
  59.   Default format is landscape scaled to fit the paper with 1 inch margins,
  60.   but the switch -p switches to portrait format. For inclusion into documents,
  61.   the switch -e is provided, that outputs a EPS file with origin at 0,0.
  62.   When using the EPS format, the switch -s### is provided to change the scale 
  63.   of the picture, the default scale is 2.0, giving a 93 mm wide picture
  64.   for a 131 pixels wide GROB.
  65.   For laserwriters connected directly to a serial port, the switch -d inserts
  66.   the ^D at the start and end of the document.
  67.  
  68. Examples:
  69.  
  70.   Printing the file graph.grb in landscape format on a UNIX box
  71.  
  72.     grob2ps graph.grb | lpr -Plaser
  73.  
  74.   Printing in portrait format to a directly connected laserwriter on COM1
  75.  
  76.     grob2ps -p -d graph.grb > COM1
  77.  
  78.   Converting the file to encapsulated postscript for a document, 
  79.   enlarging it a bit
  80.  
  81.     grob2ps -e -s3.0 graph.grb graph.ps
  82.  
  83.   Getting help
  84.  
  85.     grob2ps -h
  86.  
  87. Bugs:
  88.  
  89.   Report eventual bugs to jpensar@aton.abo.fi  
  90.  
  91. END_DOC
  92.  
  93. BEGIN_SRC grob2ps.c
  94. /*
  95.  *    grob2ps, a program for converting a hp48 GROB (GRaphic OBject)
  96.  *             to PostScript.
  97.  *
  98.  *    Author:  Johan Pensar (c) 1991
  99.  *             This program may be distributed freely as long as all
  100.  *             copyright notices are preserved. 
  101.  *             Bugreports to jpensar@aton.abo.fi
  102.  *
  103.  *    Version: 1.0, 03.09.91
  104.  */
  105.  
  106. /*#define MSC   /* if compiling on MesS-DOS */
  107.  
  108. #include <stdio.h>
  109. #include <ctype.h>
  110. #ifdef MSC
  111. #  include <time.h>
  112. #else
  113. #  include <sys/types.h>
  114. #  include <sys/time.h>
  115. #endif
  116.  
  117. #define PORTRAIT  0
  118. #define LANDSCAPE 1
  119.  
  120. /* A4 size in points */
  121. #define PAPERWIDTH  598
  122. #define PAPERHEIGHT 845
  123.  
  124. /* default scale for encapsulated mode */
  125. #define DEF_SCALE   2.0
  126.  
  127. /* default orientation in normal mode */
  128. #define DEF_ORIENT  LANDSCAPE
  129.  
  130. int orientation   = DEF_ORIENT;
  131. int eps           = 0;
  132. double scale      = DEF_SCALE;
  133. int direct        = 0;
  134. int xsize,ysize;
  135.  
  136. double atof(char *);
  137.  
  138.  
  139. /* 
  140.  * now() returns current time&date as a string 
  141.  */
  142. char * now()
  143. {
  144.   time_t date;
  145.  
  146.   if (time(&date) == -1){
  147.     perror("grob2ps: time:");
  148.     exit(1);
  149.   }
  150.  
  151.   return(ctime(&date));
  152. }
  153.  
  154.  
  155. /* 
  156.  * parse_grob() reads the grob header 
  157.  */
  158. void parse_grob()
  159. {
  160.   int chr;
  161.  
  162.   while( (chr=getchar()) != EOF ) /* The first line starting with %%HP */
  163.     if (chr == 10) 
  164.       break;
  165.  
  166.   if (chr == EOF) {
  167.     fprintf(stderr,"grob2ps: illegal grob header!!\n");
  168.     exit(1);
  169.   }
  170.  
  171.                                   /* The second line starting with */
  172.                   /* GROB xsize ysize */
  173.   if (scanf("GROB %d %d",&xsize,&ysize) != 2) {
  174.     fprintf(stderr,"grob2ps: illegal grob header!\n");
  175.     exit(1);
  176.   }
  177. }
  178.  
  179.  
  180. /*
  181.  * print_header() prints the PostScript header 
  182.  */
  183. void print_header(file)
  184. char * file;
  185. {
  186.   double xs,ys;
  187.   int xextra = 0,
  188.       yextra = 0;
  189.  
  190.   printf("%%!PS-Adobe-2.0 %s\n",(eps)?"EPSF-1.2":"");
  191.   printf("%%%%Creator: %s and grob2ps (hp48 GROB to PostScript translator)\n",
  192. #ifdef MSC
  193.          "PC user"
  194. #else
  195.      cuserid((char*) NULL)
  196. #endif
  197.   );
  198.   printf("%%%%Title: grob2ps %s (%d*%d)\n",
  199.      (*file!=(char)NULL)?file:"(stdin)",
  200.      xsize,ysize);
  201.   printf("%%%%CreationDate: %s",now());
  202.   if (eps)
  203.     printf("%%%%BoundingBox: 0 0 %d %d\n",(int)((double)xsize*scale),
  204.        (int)((double)ysize*scale));
  205.   printf("%%%%EndComments\n");
  206.  
  207.   printf("/grobimage {\n");
  208.   printf(" /picstr width 8 div ceiling cvi string def\n\n");
  209.   printf(" {1 exch sub}  settransfer\n\n");
  210.   printf(" width height 1 [1 0 0 -1 0 height]\n");
  211.   printf(" {currentfile picstr readhexstring pop\n");
  212.   printf("  0 1 width 8 div floor cvi {\n");
  213.   printf("   dup picstr exch get\n");
  214.   printf("        dup 1 and 3 bitshift\n");
  215.   printf("   exch dup 2 and 1 bitshift\n");
  216.   printf("   exch dup 4 and -1 bitshift\n");
  217.   printf("   exch dup 8 and -3 bitshift\n\n");
  218.   printf("   exch dup 16 and 3 bitshift\n");
  219.   printf("   exch dup 32 and 1 bitshift\n");
  220.   printf("   exch dup 64 and -1 bitshift\n");
  221.   printf("   exch 128 and -3 bitshift\n");
  222.   printf("   or or or or or or  or\n");
  223.   printf("   picstr 3 1 roll put\n");
  224.   printf("  } for\n");
  225.   printf(" } image\n");
  226.   printf("} def\n\n");
  227.  
  228.   printf("%%%%EndProlog\n");
  229.  
  230.   printf("\ngsave\n\n");
  231.  
  232.   if (!eps) {    
  233.     if (orientation == LANDSCAPE) {
  234.       xs = ((double)PAPERHEIGHT-144.)/(double)xsize;
  235.       ys = ((double)PAPERWIDTH-144.)/(double)ysize;
  236.       if (xs<ys) {
  237.     scale = xs;
  238.     xextra= ((double)PAPERWIDTH-144.) - (scale*(double)ysize);
  239.       }
  240.       else {
  241.     scale = ys;
  242.     yextra= ((double)PAPERHEIGHT-144.) - (scale*(double)xsize);
  243.       }       
  244.     }
  245.     else {
  246.       xs = ((double)PAPERWIDTH-144.)/(double)xsize;
  247.       ys = ((double)PAPERHEIGHT-144.)/(double)ysize;
  248.       if (xs<ys) {
  249.     scale = xs;
  250.     yextra= ((double)PAPERHEIGHT-144.) - (scale*(double)ysize);
  251.       }
  252.       else {
  253.     scale = ys;
  254.     xextra= ((double)PAPERWIDTH-144.) - (scale*(double)xsize);
  255.       }       
  256.     }
  257.  
  258.     printf("%d %d translate %s\n",
  259.        ((orientation==LANDSCAPE)?
  260.         PAPERWIDTH-(72+xextra/2):
  261.         72+xextra/2),
  262.        72+yextra/2,
  263.        (orientation==LANDSCAPE)?"90 rotate":"");
  264.     printf("%lf %lf scale\n\n",scale,scale);
  265.   }
  266.   else
  267.     printf("%lf %lf scale\n\n",scale,scale);
  268.  
  269.  
  270.   printf("/width %d def\n/height %d def\n\n",xsize,ysize);
  271. }
  272.  
  273.  
  274. /* 
  275.  * print_hexdat() prints the hexadecimal data, inserting linefeeds
  276.  *   every 78'th character to avoid to long lines
  277.  */
  278. void print_hexdat()
  279. {
  280.   int chr,chrs=-1;
  281.  
  282.   printf("grobimage\n");
  283.  
  284.   while ((chr=getchar()) != EOF)
  285.     if (isalnum(chr)) {
  286.       if (!(++chrs%78))
  287.     printf("\n");
  288.       putchar(chr);
  289.     }
  290. }
  291.  
  292.  
  293. /*
  294.  * print_trailer() prints the PostScript trailer
  295.  */
  296. void print_trailer()
  297. {
  298.   printf("\n\ngrestore\n\n");
  299.   printf("%%%%Trailer\n");
  300.   if (!eps)
  301.     printf("showpage\n");
  302. }
  303.  
  304.  
  305. /*
  306.  * ctrl_d() prints a ^D as end of job
  307.  */
  308. void ctrl_d()
  309. {
  310.     printf("\n%c\n",4);
  311. }
  312.  
  313.  
  314.  
  315. main(argc,argv)
  316. int argc;
  317. char **argv;
  318. {
  319.   static char file[256]  = "";
  320.   static char dest[256]  = "";
  321.  
  322.   /* parse switches */
  323.   while (*(++argv)) {
  324.     if (**argv == '-') {
  325.       switch (*(*argv+1)) {
  326.       case 'l': orientation = LANDSCAPE;
  327.     break;
  328.       case 'p': orientation = PORTRAIT;
  329.     break;
  330.       case 'e': eps = 1;
  331.     break;
  332.       case '?': 
  333.       case 'h':
  334.     fprintf(stderr,
  335. "\n\
  336. grob2ps, a program for converting hp48 GROB to PostScript\n\
  337. \n\
  338. Author: Johan Pensar (jpensar@aton.abo.fi) (c) 1991\n\
  339.         This program may be freely distributed as long as this\n\
  340.         copyright notice is preserved. (v 1.0)\n\
  341. \n\
  342. Usage:  grob2ps [-l [-d]|-p [-d]|-e [-s###]] [sourcefile[destinationfile]]\n\
  343. \n\
  344.         -l - landscape mode\n\
  345.         -p - portrait mode\n\
  346.         -d - direct connection, insert ^D\n\
  347.         -e - encapsulated postscript mode\n\
  348.         -s - scale (default = %3.1lf)\n\
  349. "
  350.         ,DEF_SCALE);
  351.     exit(0);
  352.       case 's': scale = atof( (char*) (*argv+2) );
  353.     if (scale <= 0.0) 
  354.       scale = DEF_SCALE;
  355.     break;
  356.       case 'd':
  357.         direct = 1;
  358.         break;
  359.     default: fprintf(stderr,"grob2ps: unknown switch '%s'\n",*argv);
  360.       }
  361.     }
  362.     else {
  363.       if (*file == (char) NULL)
  364.     strcpy(file,*argv);
  365.       else
  366.     strcpy(dest,*argv);
  367.     }
  368.   }
  369.  
  370.  
  371.   /* open files */
  372.   if (*file != (char) NULL) {
  373.     if (freopen(file,"r",stdin) == (FILE*) NULL) {
  374.       fprintf(stderr,"grob2ps: cant open grobfile %s\n",file);
  375.       exit(1);
  376.     }
  377.   }
  378.  
  379.   if (*dest != (char) NULL) {
  380.     if (freopen(dest,"w",stdout) == (FILE*) NULL) {
  381.       fprintf(stderr,"grob2ps: cant open ps-file %s\n",dest);
  382.       exit(1);
  383.     }
  384.   }
  385.  
  386.   if ((!eps) && (direct))
  387.       ctrl_d();
  388.   parse_grob();
  389.   print_header(file);
  390.   print_hexdat();
  391.   print_trailer();
  392.   if ((!eps) && (direct))
  393.       ctrl_d();
  394.  
  395.   exit(0);
  396. }
  397.  
  398. END_SRC
  399. ------------------------------------------------------------------------------
  400. Johan Pensar                                        Email: jpensar@aton.abo.fi
  401. Process Control Laboratory
  402. Abo Akademi University
  403. FINLAND
  404.